package com.wikidot.designpatterns.templatemethod;

public abstract class IceCreamMachine {
	/**
	 * This is the business method that clients can call. It hides and preserves
	 * (final method) the contract that must be followed by clients to reach
	 * desired product or behavior. The single steps are the defined abstract in
	 * this class to let them be implemented in concrete implementations.
	 * 
	 * @return The product object created according to known contract.
	 */
	public final IceCream createIceCream() {
		IceCream iceCream = new IceCream();
		// Fixed contract
		fixateCarrier(iceCream);
		applyCream(iceCream);
		applyToping(iceCream);
		pack(iceCream);
		return iceCream;
	}

	/**
	 * This step selects on what type of carrier will the ice cream be applied -
	 * whether on stick, in cone, or whatever else. The concrete selection is
	 * postponed to concrete implementation.
	 */
	protected abstract void fixateCarrier(IceCream iceCream);

	/**
	 * In this step, the cream is applied on carrier. There are several ways how
	 * to do it - make a loaf, twisted cream, ... Again, the concrete selection
	 * is postponed to concrete implementation.
	 */
	protected abstract void applyCream(IceCream iceCream);

	/**
	 * This step applies toping on the cream - chopped nuts, chocolate, ...
	 */
	protected abstract void applyToping(IceCream iceCream);

	/**
	 * This step packs the ice cream - no cover, paper cover, plastic cover, ...
	 */
	protected abstract void pack(IceCream iceCream);
}
